﻿// ----------------------------------------------------------------------
// <author name="Moses Kehengu"/>
// <copyright file="UserDetails.cs" company="Futures Group International">
//     Copyright statement. All right reserved
// </copyright>
//
// ------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using GenericTools;
using System.Web.Services.Protocols;
using DataModels.Common;
using DataModels.Enumerations;

namespace ReportingManagement
{
    public partial class UserDetails : Form
    {
        #region Private Class Variables
        private bool loaded = false;
        private UserInformation user = null;
        private UserInformation actionUser = null;
        #endregion

        #region Constructors
        public UserDetails(UserInformation actionUser)
        {
            InitializeComponent();
            this.actionUser = actionUser;

            btnReset.Enabled = false;
            btnDelete.Enabled = false;
            txtUsername.ReadOnly = false;
            this.Text = "New User Details";

            Cursor.Current = Cursors.WaitCursor;
            DataTable dataTable = Utilities.GetSupportingPartner();
            Cursor.Current = Cursors.Default;
            cboSupportingPartner.ValueMember = "Id";
            cboSupportingPartner.DisplayMember = "Name";
            cboSupportingPartner.DataSource = dataTable;


            if (this.actionUser.Level == AccessLevel.ADMINISTRATOR)
            {
                dataTable = Utilities.GetAllRegions();
            }
            else
            {
                dataTable = Utilities.GetAllRegions(this.actionUser.SupportingPartnerId);
                rdoAdministrator.Enabled = false;
                cboSupportingPartner.Enabled = false;
                cboSupportingPartner.SelectedValue = this.actionUser.SupportingPartnerId;
            }
            Cursor.Current = Cursors.Default;
            cboRegions.ValueMember = "RegionID";
            cboRegions.DisplayMember = "RegionName";
            cboRegions.DataSource = dataTable;

            lblRegion.Enabled = false;
            lblDistrict.Enabled = false;
            lblFacility.Enabled = false;

            cboRegions.Enabled = false;
            cboDistricts.Enabled = false;
            cboFacilities.Enabled = false;
        }

        public UserDetails(UserInformation targetUser, UserInformation actionUser, bool theOnlyAdministrator)
        {
            InitializeComponent();

            this.user = targetUser;
            this.actionUser = actionUser;
            FillUserInformation();
            this.Text = String.Format("User Details - {0}", this.user.FullName);
            if ((targetUser.Level == AccessLevel.ADMINISTRATOR) && theOnlyAdministrator)
            {
                gboAccessLevel.Enabled = false;
                btnDelete.Enabled = false;
            }
        }

        public UserDetails(UserInformation targetUser, UserInformation actionUser)
        {
            InitializeComponent();

            this.user = targetUser;
            this.actionUser = actionUser;
            FillUserInformation();
            this.Text = String.Format("User Details - {0}", this.user.FullName);

            txtUsername.Enabled = false;
            txtPassword.Enabled = false;
            txtConfirmPassword.Enabled = false;

            gboAccessLevel.Enabled = false;
            btnDelete.Enabled = false;
        }
        #endregion

        #region Private Helper Methods
        private void DisplayErrorMessage(Exception ex)
        {
            Cursor.Current = Cursors.Default;
            string subTitle = String.Empty;
            string message = String.Empty;

            try
            {
                SoapException soapException = (SoapException)ex;
                subTitle = "Error in XML Web service method";
                message = String.Format("{0}\n\nError Details:\n{1}", subTitle, ex.Message);
                MessageBox.Show(this, message, AppConfiguration.ApplicationName,
                    MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return;
            }
            catch { }

            if ((AppConfiguration.AccessMethod == DataAccessMethod.OFFLINE_DATA_ACCESS) ||
                (AppConfiguration.AccessMethod == DataAccessMethod.OFFLINE_DIRECT_ACCESS))
            {
                subTitle = "Error occured during processing your request";
            }
            else
            {
                subTitle = "Please make sure you have internet connection";
            }

            message = String.Format("{0}\n\nError Details:\n{1}", subTitle, ex.Message);
            MessageBox.Show(this, message, AppConfiguration.ApplicationName,
                MessageBoxButtons.OK, MessageBoxIcon.Stop);
        }

        private void FillUserInformation()
        {
            txtFirstname.Text = this.user.FirstName;
            txtLastname.Text = this.user.LastName;
            txtUsername.Text = this.user.Username;
            txtPassword.Text = this.user.Password;
            txtConfirmPassword.Text = this.user.Password;
            txtEmailAddress.Text = this.user.EmailAddress;
            txtPhoneNumber.Text = this.user.PhoneNumber;

            Cursor.Current = Cursors.WaitCursor;            
            DataTable dataTable = Utilities.GetSupportingPartner();
            Cursor.Current = Cursors.Default;
            cboSupportingPartner.ValueMember = "Id";
            cboSupportingPartner.DisplayMember = "Name";
            cboSupportingPartner.DataSource = dataTable;
            cboSupportingPartner.SelectedValue = this.user.SupportingPartnerId;

            Cursor.Current = Cursors.WaitCursor;
            if (this.actionUser.Level == AccessLevel.ADMINISTRATOR)
            {
                dataTable = Utilities.GetAllRegions();
            }
            else
            {
                dataTable = Utilities.GetAllRegions(this.actionUser.SupportingPartnerId);
                rdoAdministrator.Enabled = false;
                cboSupportingPartner.Enabled = false;
            }

            Cursor.Current = Cursors.Default;
            cboRegions.ValueMember = "RegionID";
            cboRegions.DisplayMember = "RegionName";
            cboRegions.DataSource = dataTable;               

            switch (this.user.Level)
            {
                case AccessLevel.ADMINISTRATOR:
                    rdoAdministrator.Checked = true;
                    cboRegions.SelectedIndex = 0;
                    break;

                case AccessLevel.NATION:
                    rdoNation.Checked = true;
                    cboRegions.SelectedIndex = 0;
                    break;

                case AccessLevel.REGION:
                    rdoRegion.Checked = true;
                    cboRegions.SelectedValue = user.AccessLevelValue;
                    break;

                case AccessLevel.DISTRICT:
                    rdoDistrict.Checked = true;
                    int districtID = Int32.Parse(user.AccessLevelValue);
                    Cursor.Current = Cursors.WaitCursor;
                    dataTable = Utilities.GetDistrictRegion(districtID);
                    Cursor.Current = Cursors.Default;
                    cboRegions.SelectedValue = dataTable.Rows[0]["RegionID"];
                    cboDistricts.SelectedValue = user.AccessLevelValue;
                    break;

                case AccessLevel.FACILITY:
                    rdoFacility.Checked = true;
                    string facilityCode = user.AccessLevelValue;
                    Cursor.Current = Cursors.WaitCursor;
                    dataTable = Utilities.GetFacilityRegion(facilityCode);
                    cboRegions.SelectedValue = dataTable.Rows[0]["RegionID"];
                    dataTable = Utilities.GetFacilityDistrict(facilityCode);
                    Cursor.Current = Cursors.Default;
                    cboDistricts.SelectedValue = dataTable.Rows[0]["DistrictNo"];
                    cboFacilities.SelectedValue = facilityCode;
                    break;
            }
        }
        #endregion

        #region Event Handlers
        private void btnReset_Click(object sender, EventArgs e)
        {
            FillUserInformation();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            if ((AppConfiguration.AccessMethod == DataAccessMethod.OFFLINE_DATA_ACCESS) ||
                (AppConfiguration.AccessMethod == DataAccessMethod.OFFLINE_DIRECT_ACCESS))
            {
                string message = @"The application is running in offline mode. " +
                    "You can not perform any activities that require server " +
                    "connection while you are offline. " +
                    "\n\nYou are current operation will not be processed!";
                MessageBox.Show(this, message, AppConfiguration.ApplicationName,
                    MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return;
            }

            #region Validation
            if (String.IsNullOrEmpty(txtFirstname.Text))
            {
                MessageBox.Show(this, "Please provide valid first name", AppConfiguration.ApplicationName, 
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtFirstname.Focus();
                return;
            }

            if (String.IsNullOrEmpty(txtLastname.Text))
            {
                MessageBox.Show(this, "Please provide valid last name", AppConfiguration.ApplicationName,
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtLastname.Focus();
                return;
            }

            if (String.IsNullOrEmpty(txtUsername.Text))
            {
                MessageBox.Show(this, "Please provide valid username", AppConfiguration.ApplicationName,
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtUsername.Focus();
                return;
            }

            if (String.IsNullOrEmpty(txtPassword.Text))
            {
                MessageBox.Show(this, "Please provide valid password", AppConfiguration.ApplicationName,
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtPassword.Focus();
                return;
            }

            if (String.IsNullOrEmpty(txtConfirmPassword.Text))
            {
                MessageBox.Show(this, "Please provide valid password confirmation", AppConfiguration.ApplicationName,
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtConfirmPassword.Focus();
                return;
            }

            if (txtPassword.Text != txtConfirmPassword.Text)
            {
                MessageBox.Show(this, "Password and it confirmation do not match!", AppConfiguration.ApplicationName,
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtConfirmPassword.Focus();
                return;
            }

            if (String.IsNullOrEmpty(txtEmailAddress.Text))
            {
                MessageBox.Show(this, "Please provide valid email address", AppConfiguration.ApplicationName,
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtEmailAddress.Focus();
                return;
            }            

            if (!txtEmailAddress.Text.Contains("@"))
            {
                DialogResult response = MessageBox.Show(this, "Are you sure you have provided valid e-mail address?",
                    AppConfiguration.ApplicationName, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (response == System.Windows.Forms.DialogResult.No)
                {
                    txtEmailAddress.SelectAll();
                    return;
                }
            }

            if (String.IsNullOrEmpty(txtPhoneNumber.Text))
            {
                MessageBox.Show(this, "Please provide valid phone number", AppConfiguration.ApplicationName,
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtPhoneNumber.Focus();
                return;
            }
            #endregion

            #region Saving Changes
            #region Determining Access Level parameters
            AccessLevel level = AccessLevel.RESTRICTED;
            string value = "00000000";

            if (rdoAdministrator.Checked) level = AccessLevel.ADMINISTRATOR;
            if (rdoNation.Checked) level = AccessLevel.NATION;
            
            if (rdoRegion.Checked)
            {
                level = AccessLevel.REGION;
                value = cboRegions.SelectedValue.ToString();
            }
            if (rdoDistrict.Checked)
            {
                level = AccessLevel.DISTRICT;
                value = cboDistricts.SelectedValue.ToString();
            }
            if (rdoFacility.Checked)
            {
                level = AccessLevel.FACILITY;
                value = cboFacilities.SelectedValue.ToString();
            }
            #endregion

            try
            {
                int supportingPartnerId = Int32.Parse(cboSupportingPartner.SelectedValue.ToString());
                if (this.user == null)
                {
                    #region Adding New User
                    Cursor.Current = Cursors.WaitCursor;
                    bool usernameAvailable = UserInformation.IsUsernameAvailable(txtUsername.Text);
                    Cursor.Current = Cursors.Default;
                    if (usernameAvailable)
                    {
                        Cursor.Current = Cursors.WaitCursor;
                        UserInformation userInfo = UserInformation.CreateNewUser(txtFirstname.Text, txtLastname.Text,
                            txtUsername.Text, txtPassword.Text, txtEmailAddress.Text, txtPhoneNumber.Text, level, 
                            value, supportingPartnerId, this.actionUser.ID);
                        Cursor.Current = Cursors.Default;
                        if (userInfo == null)
                        {
                            MessageBox.Show(this, "Saving of User information did not complete!",
                                AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                            this.Close();
                        }
                        else
                        {
                            this.user = userInfo;
                            MessageBox.Show(this, "You have successfully saved user information",
                                AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information);
                            this.DialogResult = System.Windows.Forms.DialogResult.OK;
                            this.Close();
                        }
                    }
                    else
                    {
                        MessageBox.Show(this, "Username you have selected is already in use. Please select another username",
                                AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        txtUsername.Focus();
                        return;
                    }
                    #endregion
                }
                else
                {
                    #region Updating User Information
                    this.user.Level = level;
                    this.user.AccessLevelValue = value;
                    this.user.FirstName = txtFirstname.Text;
                    this.user.LastName = txtLastname.Text;
                    this.user.Password = txtPassword.Text;
                    this.user.EmailAddress = txtEmailAddress.Text;
                    this.user.PhoneNumber = txtPhoneNumber.Text;
                    this.user.SupportingPartnerId = supportingPartnerId;
                    
                    Cursor.Current = Cursors.WaitCursor;
                    bool success = this.user.Save(this.actionUser.ID);
                    Cursor.Current = Cursors.Default;
                    if (success)
                    {
                        MessageBox.Show(this, "You have successfully saved user information",
                            AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information);
                        this.DialogResult = System.Windows.Forms.DialogResult.OK;
                        this.Close();
                    }
                    else
                    {
                        MessageBox.Show(this, "Saving of User information did not complete!",
                            AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
                        this.Close();
                    }
                    #endregion
                }
            }
            catch (Exception ex)
            {
                DisplayErrorMessage(ex);
            }
            #endregion
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            if ((AppConfiguration.AccessMethod == DataAccessMethod.OFFLINE_DATA_ACCESS) ||
                (AppConfiguration.AccessMethod == DataAccessMethod.OFFLINE_DIRECT_ACCESS))
            {
                string message = @"The application is running in offline mode. " +
                    "You can not perform any activities that require server " +
                    "connection while you are offline. " +
                    "\n\nYou are current operation will not be processed!";
                MessageBox.Show(this, message, AppConfiguration.ApplicationName,
                    MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return;
            }

            try
            {
                string fullname = this.user.FullName;
                DialogResult response = MessageBox.Show(this,
                    String.Format("Are you sure you want to delete {0}?", fullname),
                    AppConfiguration.ApplicationName, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (response == System.Windows.Forms.DialogResult.Yes)
                {
                    Cursor.Current = Cursors.WaitCursor;
                    bool success = this.user.Delete(this.actionUser.ID);
                    Cursor.Current = Cursors.Default;
                    if (success)
                    {
                        MessageBox.Show(this, String.Format("You have successfully deleted {0}", fullname),
                            AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information);
                        this.DialogResult = System.Windows.Forms.DialogResult.OK;
                        this.Close();
                    }
                    else
                    {
                        MessageBox.Show(this, String.Format("Could not delete {0} from the system!", fullname),
                            AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
                        this.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                DisplayErrorMessage(ex);
            }
        }

        private void UserDetails_Load(object sender, EventArgs e)
        {
            this.loaded = true;
        }

        private void cboRegions_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cboDistricts.Enabled)
            {
                try
                {
                    int regionID = int.Parse(cboRegions.SelectedValue.ToString());
                    Cursor.Current = Cursors.WaitCursor;
                    
                    DataTable dataTable = null;
                    if (this.actionUser.Level == AccessLevel.ADMINISTRATOR) dataTable = Utilities.GetDistrictsByRegion(regionID);
                    else dataTable = Utilities.GetDistrictsByRegion(regionID, this.actionUser.SupportingPartnerId);
                    
                    Cursor.Current = Cursors.Default;
                    cboDistricts.ValueMember = "DistrictNo";
                    cboDistricts.DisplayMember = "District";
                    cboDistricts.DataSource = dataTable;
                }
                catch (Exception ex)
                {
                    if (loaded) DisplayErrorMessage(ex);
                }
            }
        }

        private void cboDistricts_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cboFacilities.Enabled)
            {
                try
                {
                    int districtID = Int32.Parse(cboDistricts.SelectedValue.ToString());
                    Cursor.Current = Cursors.WaitCursor;

                    DataTable dataTable = null;
                    if (this.actionUser.Level == AccessLevel.ADMINISTRATOR) dataTable = Utilities.GetFacilitiesDetailsByDistrict(districtID);
                    else dataTable = Utilities.GetFacilitiesDetailsByDistrict(districtID, this.actionUser.SupportingPartnerId);

                    Cursor.Current = Cursors.Default;
                    cboFacilities.ValueMember = "FacCode";
                    cboFacilities.DisplayMember = "FacName";
                    cboFacilities.DataSource = dataTable;
                }
                catch (Exception ex)
                {
                    if (loaded) DisplayErrorMessage(ex);
                }
            }
        }

        private void rdoAdministrator_CheckedChanged(object sender, EventArgs e)
        {
            if (rdoAdministrator.Checked)
            {
                lblRegion.Enabled = false;
                lblDistrict.Enabled = false;
                lblFacility.Enabled = false;

                cboRegions.Enabled = false;
                cboDistricts.Enabled = false;
                cboFacilities.Enabled = false;
            }
        }

        private void rdoNation_CheckedChanged(object sender, EventArgs e)
        {
            if (rdoNation.Checked)
            {
                lblRegion.Enabled = false;
                lblDistrict.Enabled = false;
                lblFacility.Enabled = false;

                cboRegions.Enabled = false;
                cboDistricts.Enabled = false;
                cboFacilities.Enabled = false;
            }
        }

        private void rdoRegion_CheckedChanged(object sender, EventArgs e)
        {
            if (rdoRegion.Checked)
            {
                lblRegion.Enabled = true;
                lblDistrict.Enabled = false;
                lblFacility.Enabled = false;

                cboRegions.Enabled = true;
                cboDistricts.Enabled = false;
                cboFacilities.Enabled = false;
            }
        }

        private void rdoDistrict_CheckedChanged(object sender, EventArgs e)
        {
            if (rdoDistrict.Checked)
            {
                lblRegion.Enabled = true;
                lblDistrict.Enabled = true;
                lblFacility.Enabled = false;

                cboRegions.Enabled = true;
                cboDistricts.Enabled = true;
                cboFacilities.Enabled = false;

                cboRegions_SelectedIndexChanged(null, null);
            }
        }

        private void rdoFacility_CheckedChanged(object sender, EventArgs e)
        {
            if (rdoFacility.Checked)
            {
                lblRegion.Enabled = true;
                lblDistrict.Enabled = true;
                lblFacility.Enabled = true;

                cboRegions.Enabled = true;
                cboDistricts.Enabled = true;
                cboFacilities.Enabled = true;

                cboRegions_SelectedIndexChanged(null, null);
                cboDistricts_SelectedIndexChanged(null, null);
            }
        }
        #endregion

        #region Public Properties
        public UserInformation User
        {
            get { return this.user; }
        }
        #endregion
    }
}
